package com.ruoyi.common.mybatisplus;

import com.baomidou.mybatisplus.core.conditions.interfaces.Compare;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;

import java.util.Collection;
import java.util.Map;

/**
 * 牛逼的wrapper构造
 * 描述：实体类使用注解 WhereType
 * 默认 为等于，其他的使用枚举；参考InStorePageVo
 *
 * @author: 张鹏
 * @Date: 2018/11/26
 */
@Data
public class QueryWrTool {

    private static final Map<QueryEnum, QueryWrFun> typeFunc = Map.of(
            QueryEnum.EQ, Compare::eq,
            QueryEnum.NE, (w, f, v) -> {
                w.ne(f, v);
                w.isNull(f);
            },
            QueryEnum.IN, (w, f, v) -> {
                if (v instanceof Collection) {
                    w.in(f, (Collection<?>) v);
                } else if (v instanceof Object[]) {
                    w.in(f, (Object[]) v);
                } else {
                    w.in(f, v.toString());
                }
            },
            QueryEnum.NOT_IN, (w, f, v) -> {
                if (v instanceof Collection) {
                    w.notIn(f, (Collection<?>) v);
                } else if (v instanceof Object[]) {
                    w.notIn(f, (Object[]) v);
                } else {
                    w.notIn(f, v.toString());
                }
                w.isNull(f);
            },
            QueryEnum.NOT_LIKE, (w, f, v) -> {
                w.notLike(f, v);
                w.isNull(f);
            },
            QueryEnum.LIKE, Compare::like,
            QueryEnum.LE, (w, k, v) -> {
                w.le(k, v);
            },
            QueryEnum.LT, (w, k, v) -> {
                w.lt(k, v);
            },
            QueryEnum.GE, (w, k, v) -> {
                w.ge(k, v);
            },
            QueryEnum.GT, (w, k, v) -> {
                w.gt(k, v);
            }

    );

    /**
     * 封装成需要的wrapper
     *
     * @param t 实体对象
     * @return
     */
    public static <T> QueryWrapper<T> queryWrapper(T t) {
        return queryWrapper(t, new QueryWrapper<>());
    }

    /**
     * 执行
     *
     * @param t       obj
     * @param wrapper
     */
    public static <T> QueryWrapper<T> queryWrapper(T t, QueryWrapper<T> wrapper) {
        if (wrapper == null) {
            wrapper = new QueryWrapper<>();
        }
        //反射获取属性
        if (t == null) {
            return wrapper;
        }
        TableInfo info = TableInfoHelper.getTableInfo(t.getClass());

        for (TableFieldInfo field : info.getFieldList()) {
            queryWrapper(t, field, wrapper);
        }
        return wrapper;
    }


    /**
     * 封装成需要的wrapper
     *
     * @param t 实体对象
     * @return
     */
    public static <T extends BaseEntity> QueryWrapper<T> queryWrapperByBaseEntity(T t) {
        return queryWrapperByBaseEntity(t, new QueryWrapper<>());
    }

    /**
     * 执行
     *
     * @param t       obj
     * @param wrapper
     */
    public static <T extends BaseEntity> QueryWrapper<T> queryWrapperByBaseEntity(T t, QueryWrapper<T> wrapper) {
        //反射获取属性
        if (t == null) {
            return null;
        }
        wrapper = queryWrapper(t, wrapper);

        String begin_createTime = t.getParams().getOrDefault("begin_createTime", "").toString();
        String end_createTime = t.getParams().getOrDefault("end_createTime", "").toString();
        wrapper.ge(StringUtils.isNotBlank(begin_createTime), "create_time", begin_createTime);
        wrapper.le(StringUtils.isNotBlank(end_createTime), "create_time", end_createTime);

        String begin_updateTime = t.getParams().getOrDefault("begin_updateTime", "").toString();
        String end_updateTime = t.getParams().getOrDefault("end_updateTime", "").toString();
        wrapper.ge(StringUtils.isNotBlank(begin_updateTime), "create_time", begin_updateTime);
        wrapper.le(StringUtils.isNotBlank(end_updateTime), "create_time", end_updateTime);
        return wrapper;
    }



    private static <T> QueryWrapper<T> queryWrapper(T t, TableFieldInfo field, QueryWrapper<T> wrapper) {

        Object val = Reflect.invokeGetter(t, field.getProperty());
        if (val != null && !"".equals(val.toString())) {
            QueryWr queryWrappy = field.getField().getAnnotation(QueryWr.class);
            //没有注解，取默认为下划线拼接
            if (queryWrappy == null) {
                // 执行方法
                typeFunc.get(QueryEnum.EQ).queryFunc(wrapper, field.getColumn(), val);
            } else {
                if (queryWrappy.ignore()) {
                    return wrapper;
                } else {
                    // 执行方法
                    typeFunc.get(queryWrappy.type()).queryFunc(wrapper, field.getColumn(), val);
                }
            }
        }
        return wrapper;
    }
}